// Package localLock
// @File: chanMutex.go
// @Description:
// @Author: YaoRuiQi
// @Date: 2025/8/29 16:27

package localLock

import (
	"context"
	"time"
)

// Mutex
// @Description: 实现一个有获取超时时间的锁
type Mutex struct {
	lockChan chan struct{}
	IsLock   bool
}

// NewMutex
//
//	@Description: 创建一个锁
//	@return *Mutex
func NewMutex() *Mutex {
	return &Mutex{lockChan: make(chan struct{}, 1)}
}

// Lock
//
//	@Description: 获取锁
func (m *Mutex) Lock() {
	m.lockChan <- struct{}{}
	m.IsLock = true
}

// UnLock
//
//	@Description: 释放锁，如果chan有内容，表示之前是锁定状态，则释放锁。如果chan没有内容，则表示之前是解锁状态，则不处理。
func (m *Mutex) UnLock() error {
	select {
	case <-m.lockChan:
		m.IsLock = false
		return nil
	default:
		return ErrLockLost
	}
}

// TryLock
//
//	@Description: 尝试获取锁，如果获取成功，则返回true，否则返回false
//	@return bool 获取锁成功返回true，否则返回false
func (m *Mutex) TryLock() bool {
	select {
	case m.lockChan <- struct{}{}:
		m.IsLock = true
		return true
	default:
		return false
	}
}

// TryLockWithContext
//
//	@Description: 尝试获取锁，如果获取成功，则返回true，否则返回false
//	@param ctx 带有超时控制的context
func (m *Mutex) TryLockWithContext(ctx context.Context) error {
	select {
	case m.lockChan <- struct{}{}:
		m.IsLock = true
		return nil
	case <-ctx.Done():
		return ErrLockTimeout
	}
}

// TryLockWithTimeout
//
//	@Description: 尝试获取锁，如果获取成功，则返回true，否则返回false
//	@param duration 锁超时时间
func (m *Mutex) TryLockWithTimeout(duration time.Duration) error {
	ctx, cancel := context.WithTimeout(context.Background(), duration)
	defer cancel()

	return m.TryLockWithContext(ctx)
}
